﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using XNAGuiLib.GuiLibAction;
using Microsoft.Xna.Framework.Graphics;

namespace XNAGuiLib
{
    public class InterfaceManager : DrawableGameComponent
    {

        private static InterfaceManager _instance;

        #region Field - InterfaceObjects
        protected List<InterfaceObject> _ios = new List<InterfaceObject>();
        /// <summary>
        /// gets the List of interfaceObjects registered on this InterfaceManager
        /// </summary>
        public List<InterfaceObject> InterfaceObjects
        {
            get
            {
                return _ios;
            }
        }
        #endregion

        #region Field - Count
        /// <summary>
        /// gets the total amount of InterfaceObjects registered on this InterfaceManager
        /// </summary>
        public int Count
        {
            get
            {
                return _ios.Count;
            }
        }
        #endregion

        #region Field - Sprite
        protected SpriteBatch _sprite;
        /// <summary>
        /// gets or sets the InterfaceManagers SpriteBatch
        /// </summary>
        public SpriteBatch Sprite
        {
            get
            {
                return _sprite;
            }
            set
            {
                _sprite = value;
            }
        }
        #endregion


        #region Static Method - GetInstance(Game game)
        public static InterfaceManager GetInstance(Game game)
        {
            if (_instance == null)
                _instance = new InterfaceManager(game);

            return _instance;
        }
        #endregion

        #region Constructor - InterfaceManager(Game game)
        private InterfaceManager(Game game) : base(game)
        {
            // _sprite = new SpriteBatch(game.GraphicsDevice);
        }
        #endregion



        #region Method - Add(InterfaceObject obj)
        /// <summary>
        /// adds the given InterfaceObject and all Sub-InterfaceObjects to the InterfaceManagers list
        /// </summary>
        /// <param name="obj"></param>
        public void Add(InterfaceObject obj)
        {
            if (!_ios.Contains(obj))
            {
                _ios.Add(obj);
            }

            foreach (InterfaceObject io in obj.InterfaceObjects)
            {
                Add(io);
            }
        }
        #endregion

        #region Method - Remove(InterfaceObject obj)
        /// <summary>
        /// removes the given InterfaceObject and all Sub-InterfacObjects from the InterfaceManagers list
        /// </summary>
        /// <param name="obj">InterfaceObject to be completely removed</param>
        public void Remove(InterfaceObject obj)
        {
            if (_ios.Contains(obj))
            {
                _ios.Remove(obj);
            }

            foreach (InterfaceObject io in obj.InterfaceObjects)
            {
                Remove(io);
            }
        }
        #endregion

        #region Method - Get(string name)
        /// <summary>
        /// gets the first occurence of InterfaceObject in the InterfaceManagers list
        /// </summary>
        /// <param name="name">name of the InterfaceObject to look for</param>
        /// <returns>the first InterfacObject with the given name or null (if none found in list)</returns>
        public InterfaceObject Get(string name)
        {
            foreach (InterfaceObject io in _ios)
            {
                if (io.Name.Equals(name)) return io;
            }
            
            return null;
        }
        #endregion


        #region Method - Enable(Action action)
        public void Enable(Action action)
        {
            foreach (InterfaceObject io in _ios)
            {
                foreach (Action act in io.Actions)
                {
                    if (act.Equals(action)) act.Enable();
                }
            }
        }
        #endregion

        #region Method - Disable(Action action)
        public void Disable(Action action)
        {
            foreach (InterfaceObject io in _ios)
            {
                foreach (Action act in io.Actions)
                {
                    if (act.Equals(action)) act.Disable();
                }
            }
        }
        #endregion

        #region Method - EnableAll()
        public void EnableAll()
        {
            foreach (InterfaceObject io in _ios)
            {
                foreach (Action act in io.Actions)
                {
                    act.Enable();
                }
            }
        }
        #endregion

        #region Method - DisableAll()
        public void DisableAll()
        {
            foreach (InterfaceObject io in _ios)
            {
                foreach (Action act in io.Actions)
                {
                    act.Disable();
                }
            }
        }
        #endregion

        #region Method - EnableAllExcept(Action action)
        public void EnableAllExcept(Action action)
        {
            foreach (InterfaceObject io in _ios)
            {
                foreach (Action act in io.Actions)
                {
                    if (!act.Equals(action)) act.Enable();
                    else act.Disable();
                }
            }
        }
        #endregion

        #region Method - DisableAllExcept(Action action)
        public void DisableAllExcept(Action action)
        {
            foreach (InterfaceObject io in _ios)
            {
                foreach (Action act in io.Actions)
                {
                    if (act.Equals(action)) act.Enable();
                    else act.Disable();
                }
            }
        }
        #endregion



        #region Override Method - Update(GameTime gameTime)
        public override void Update(GameTime gameTime)
        {

        }
        #endregion

        #region Override Method - Draw(GameTime gameTime)
        public override void Draw(GameTime gameTime)
        {
            _sprite.Begin();

            foreach (InterfaceObject io in _ios)
            {
                io.Draw(gameTime, _sprite);
            }

            _sprite.End();
        }
        #endregion

    }
}